using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using DataAccess;
using Task.Contracts;
using NHibernate;
using NHibernate.Expression;
using System.Data;
//using System.Configuration;


namespace Task
{
    public class FriendsTask : IFriendsTask
    {
        private int Fr = 10;

        public int FriendsPerPage
        {
            get { return Fr; }
            set { Fr = value; }
        }

        private int  In= 5;

        public int InvitationsPerPage
        {
            get { return In; }
            set { In = value; }
        }

        public int GetNumberOfFriends(int UserId)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> listAllUserFriends = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", UserId),NHibernate.Expression.Expression.Eq("status","y")));

            int NumberOfFriends = listAllUserFriends.Count;

            return NumberOfFriends;

        }

        public int[] GetCommonFriends(int UserId, int SessionId)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> listAllUsersFriends = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", UserId), NHibernate.Expression.Expression.Eq("status", "y")));

            int[] iDFriend = new int[listAllUsersFriends.Count];
            int[] iDCommonFriends = new int[listAllUsersFriends.Count];
            int ii = 0;

            foreach (friend element in listAllUsersFriends)
            {
                if (ii < iDFriend.Length)
                    iDFriend[ii] = (int)element.invited_user_id;

                ii++;
            }

            int jj = 0;
            for (int i = 0; i < iDFriend.Length; i++)
            {
                listAllUsersFriends = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", SessionId), NHibernate.Expression.Expression.Eq("invited_user_id", iDFriend[i])));
                if (listAllUsersFriends.Count > 0)
                {
                    foreach (friend element in listAllUsersFriends)
                    {
                        if (jj < iDCommonFriends.Length)
                            iDCommonFriends[jj] = (int)element.invited_user_id;

                        jj++;
                    }

                }
            }

            return iDCommonFriends;
        }

        public DataTable GetAllInfoFriends(int UserId, int pageNr)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> listAllUsersFriends;

            if (pageNr == 1)
                listAllUsersFriends = sampleFriendFactory.GetByCriteria(0, FriendsPerPage, "invited_user_id", true,NHibernate.Expression.Expression.And( NHibernate.Expression.Expression.Eq("inviting_user_id", UserId),NHibernate.Expression.Expression.Eq("status","y")));
            else
                listAllUsersFriends = sampleFriendFactory.GetByCriteria((pageNr - 1) * FriendsPerPage, FriendsPerPage, "invited_user_id", true, NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", UserId), NHibernate.Expression.Expression.Eq("status", "y")));


            int[] iDFriend = new int[listAllUsersFriends.Count];
            int ii = 0;

            foreach (friend element in listAllUsersFriends)
            {
                if (ii < iDFriend.Length)
                    iDFriend[ii] = (int)element.invited_user_id;

                ii++;
            }


            NHibernateDao<user, int> sampleUserFactory = new NHibernateDao<user, int>();

            List<user> listInfoFriend = new List<user>();
            List<user> tmp = new List<user>();

            for (int ind = 0; ind < iDFriend.Length; ind++)
            {
                tmp = sampleUserFactory.GetByCriteria(NHibernate.Expression.Expression.Eq("id", iDFriend[ind]));
                listInfoFriend.Add(tmp[0]);
            }

            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add("login", typeof(string));
            dt.Columns.Add("id", typeof(int));

            foreach (user el in listInfoFriend)
            {
                if (el.login.ToString().Length != 0)
                {
                    dr = dt.NewRow();
                    dr[0] = el.login.ToString();
                    dr[1] = el.id;


                    dt.Rows.Add(dr);
                }
            }
            return dt;

        }

        public DataTable GetSentInvitations(int UserId, int pageNr)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> listAllInvFriends;

            if (pageNr == 1)
                listAllInvFriends = sampleFriendFactory.GetByCriteria(0, InvitationsPerPage, "invited_user_id", true, NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", UserId), NHibernate.Expression.Expression.Eq("status", "n")));
            else
                listAllInvFriends = sampleFriendFactory.GetByCriteria((pageNr - 1) * InvitationsPerPage, InvitationsPerPage, "invited_user_id", true, NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", UserId), NHibernate.Expression.Expression.Eq("status", "n")));


            int[] iDFriend = new int[listAllInvFriends.Count];
            int ii = 0;

            foreach (friend element in listAllInvFriends)
            {
                if (ii < iDFriend.Length)
                    iDFriend[ii] = (int)element.invited_user_id;

                ii++;
            }


            NHibernateDao<user, int> sampleUserFactory = new NHibernateDao<user, int>();

            List<user> listInfoFriend = new List<user>();
            List<user> tmp = new List<user>();

            for (int ind = 0; ind < iDFriend.Length; ind++)
            {
                tmp = sampleUserFactory.GetByCriteria(NHibernate.Expression.Expression.Eq("id", iDFriend[ind]));
                listInfoFriend.Add(tmp[0]);
            }

            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add("login", typeof(string));
            dt.Columns.Add("id", typeof(int));

            foreach (user el in listInfoFriend)
            {
                if (el.login.ToString().Length != 0)
                {
                    dr = dt.NewRow();
                    dr[0] = el.login.ToString();
                    dr[1] = el.id;


                    dt.Rows.Add(dr);
                }
            }
            return dt;

        }

        public DataTable GetReceivedInvitations(int UserId, int pageNr)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> listAllRecInv;

            if (pageNr == 1)
                listAllRecInv = sampleFriendFactory.GetByCriteria(0, InvitationsPerPage, "inviting_user_id", true, NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("invited_user_id", UserId), NHibernate.Expression.Expression.Eq("status", "n")));
            else
                listAllRecInv = sampleFriendFactory.GetByCriteria((pageNr - 1) * InvitationsPerPage, InvitationsPerPage, "inviting_user_id", true, NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("invited_user_id", UserId), NHibernate.Expression.Expression.Eq("status", "n")));


            int[] iDFriend = new int[listAllRecInv.Count];
            int ii = 0;

            foreach (friend element in listAllRecInv)
            {
                if (ii < iDFriend.Length)
                    iDFriend[ii] = (int)element.inviting_user_id;

                ii++;
            }


            NHibernateDao<user, int> sampleUserFactory = new NHibernateDao<user, int>();

            List<user> listInfoFriend = new List<user>();
            List<user> tmp = new List<user>();

            for (int ind = 0; ind < iDFriend.Length; ind++)
            {
                tmp = sampleUserFactory.GetByCriteria(NHibernate.Expression.Expression.Eq("id", iDFriend[ind]));
                listInfoFriend.Add(tmp[0]);
            }

            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add("login", typeof(string));
            dt.Columns.Add("id", typeof(int));

            foreach (user el in listInfoFriend)
            {
                if (el.login.ToString().Length != 0)
                {
                    dr = dt.NewRow();
                    dr[0] = el.login.ToString();
                    dr[1] = el.id;


                    dt.Rows.Add(dr);
                }
            }
            return dt;

        }

        public void DeleteFriend(int UserId, int DelFr)
       {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> friendToDel = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("invited_user_id", DelFr), NHibernate.Expression.Expression.Eq("inviting_user_id", UserId)));

            foreach (friend element in friendToDel)
            {

                sampleFriendFactory.Delete(element);

            }


        }

        public void RefuseInvitation(int UserId, int Fr)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> invToDel = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", Fr), NHibernate.Expression.Expression.Eq("invited_user_id", UserId)));

            foreach (friend element in invToDel)
            {

                sampleFriendFactory.Delete(element);

            }


        }

        public void SendInvitationToFriend(int UserId, int AddFr)
        {
           NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
           NHibernateDao<user, int> sampleUserFactory = new NHibernateDao<user, int>();

          //List<friend> listAllFriends = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.Eq( "inviting_user_id",UserId));
          //  friend f=new friend();
          //  f.invited_user_id=AddFr;
          //  f.inviting_user_id=UserId;
          //  f.status="n";

            friend f = new friend();
            f.user = sampleUserFactory.GetById(UserId, false);
            f.user1 = sampleUserFactory.GetById(AddFr, false);
            f.status = "n";

            //listAllFriends.Add(f);
          
            //user u = sampleUserFactory.GetById(UserId, false);
            //u.friends = listAllFriends;
            
            //f.user = u;

          //sampleUserFactory.SaveOrUpdate(u);
          //sampleUserFactory.CommitChanges();
            sampleFriendFactory.Save(f);
          //sampleFriendFactory.CommitChanges();
          
        }

        public void AddFriend(int UserId, int AddFr)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> friendToAdd = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("invited_user_id", AddFr), NHibernate.Expression.Expression.Eq("inviting_user_id", UserId)));

            if (friendToAdd.Count == 1)
            {
                foreach (friend element in friendToAdd)
                {
                    element.status = "y";
                    sampleFriendFactory.SaveOrUpdate(element);

                }
            }
           
            

        }

        public void AcceptInvitation(int UserId, int Fr)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> friendInvMe = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", Fr), NHibernate.Expression.Expression.Eq("invited_user_id", UserId)));

            if (friendInvMe.Count == 1)
            {
                foreach (friend element in friendInvMe)
                {
                    element.status = "y";
                    sampleFriendFactory.SaveOrUpdate(element);

                }
            }
        }

        public string GetLoginOfFriend(int UserId)
        {
            NHibernateDao<user, int> sampleUserFactory = new NHibernateDao<user, int>();
            user u= sampleUserFactory.GetById(UserId,false);
            return u.login;

        }

        public int GetNumberOfSentInvitations(int UserId)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> listAllInvFriends = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("inviting_user_id", UserId), NHibernate.Expression.Expression.Eq("status", "n")));

            int NumberOfInv = listAllInvFriends.Count;

            return NumberOfInv;

        }

        public int GetNumberOfReceivedInvitations(int UserId)
        {
            NHibernateDao<friend, int> sampleFriendFactory = new NHibernateDao<friend, int>();
            List<friend> listAllInvFriends = sampleFriendFactory.GetByCriteria(NHibernate.Expression.Expression.And(NHibernate.Expression.Expression.Eq("invited_user_id", UserId), NHibernate.Expression.Expression.Eq("status", "n")));

            int NumberOfInv = listAllInvFriends.Count;

            return NumberOfInv;

        }

        public IList<user> GetFriendsForUser(int userId, int howMany)
        {
            ISession session = NHibernateSessionManager.Instance.GetSession();
            //NHibernateDao<art, int> artFactory = new NHibernateDao<art, int>();

            IList<user> users = session.CreateQuery("from user as u where u.id in (select fr1.user1.id from friend as fr1 where status = 'y' and fr1.user.id = :userId) or u.id in (select fr2.user.id from friend as fr2 where status = 'y' and fr2.user1.id = :userId)").SetParameter("userId", userId.ToString()).SetMaxResults(howMany).List<user>();

            return users;
        }

    }
}

